import axios from 'axios'
import { ElMessage, ElLoading, ElNotification } from 'element-plus'
import router from '@/router' // 导入全局路由实例（替换 useRouter()）

// 1. 创建 Axios 实例（读取环境变量配置）
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL, // 后端基础地址（从环境变量获取）
  timeout: import.meta.env.VITE_API_TIMEOUT || 15000, // 超时时间（默认15秒）
  headers: {
    'Content-Type': 'application/json;charset=utf-8' // 默认 JSON 格式
  }
})

// 2. 全局状态管理（重复请求拦截、加载动画）
const pendingRequests = new Map() // 存储重复请求（避免短时间重复调用）
let loadingInstance = null // 加载动画实例
let loadingCount = 0 // 加载动画计数（多请求共享一个动画）

// 3. 生成请求唯一标识（用于重复请求拦截）
const generateRequestKey = (config) => {
  const { method, url, params, data } = config
  return `${method}-${url}-${JSON.stringify(params || {})}-${JSON.stringify(data || {})}`
}

// 4. 移除重复请求（取消之前的重复请求）
const removePendingRequest = (config) => {
  const requestKey = generateRequestKey(config)
  if (pendingRequests.has(requestKey)) {
    const cancelToken = pendingRequests.get(requestKey)
    cancelToken(`重复请求已取消：${requestKey}`)
    pendingRequests.delete(requestKey)
  }
}

// 5. 显示加载动画（支持通过 config 关闭）
const showLoading = (config) => {
  if (config.showLoading === false) return
  if (loadingCount === 0) {
    loadingInstance = ElLoading.service({
      lock: true,
      text: config.loadingText || '加载中...',
      background: 'rgba(0, 0, 0, 0.1)'
    })
  }
  loadingCount++
}

// 6. 隐藏加载动画（延迟关闭，避免闪烁）
const hideLoading = (config) => {
  if (config.showLoading === false) return
  if (loadingCount > 0) {
    loadingCount--
    if (loadingCount === 0) {
      setTimeout(() => {
        loadingInstance?.close()
      }, 300)
    }
  }
}

// 7. 请求拦截器（添加 Token、重复请求拦截、加载动画）
service.interceptors.request.use(
  (config) => {
    // 7.1 移除重复请求
    removePendingRequest(config)
    // 7.2 添加当前请求到待处理列表（用于后续拦截）
    config.cancelToken = new axios.CancelToken((cancel) => {
      pendingRequests.set(generateRequestKey(config), cancel)
    })

    // 7.3 显示加载动画（默认显示）
    showLoading(config)

    // 7.4 添加 Token（从 localStorage 获取，后端若不需要可删除）
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }

    // 7.5 开发环境打印请求日志（方便调试）
    if (import.meta.env.VITE_API_LOG === 'true') {
      console.log(`[请求] ${config.method.toUpperCase()} ${config.url}`, {
        params: config.params,
        data: config.data,
        headers: config.headers
      })
    }

    return config
  },
  (error) => {
    // 请求参数错误：隐藏加载动画 + 提示
    hideLoading(error.config || {})
    ElMessage.error('请求参数错误，请检查请求格式')
    return Promise.reject(error)
  }
)

// 8. 响应拦截器（统一错误处理、数据解析）
service.interceptors.response.use(
  (response) => {
    // 8.1 移除待处理请求
    removePendingRequest(response.config)
    // 8.2 隐藏加载动画
    hideLoading(response.config)

    const config = response.config
    const responseData = response.data

    // 8.3 开发环境打印响应日志
    if (import.meta.env.VITE_API_LOG === 'true') {
      console.log(`[响应] ${config.method.toUpperCase()} ${config.url}`, {
        status: response.status,
        data: responseData
      })
    }

    // 8.4 统一数据解析（需与后端确认返回格式！示例：{ code, message, data }）
    const { code, message, data } = responseData
    if (code === 200 || code === 0) {
      // 按需返回完整响应或仅数据
      return config.returnFullResponse ? responseData : data
    } else {
      // 业务错误：提示错误信息
      const errorMsg = message || '操作失败，请稍后重试'
      if (config.errorType === 'notification') {
        ElNotification.error({ title: '错误', message: errorMsg })
      } else {
        ElMessage.error(errorMsg)
      }
      return Promise.reject(new Error(errorMsg))
    }
  },
  (error) => {
    // 8.5 网络错误/HTTP 状态码错误处理
    const config = error.config || {}
    hideLoading(config)
    removePendingRequest(config)

    // 区分“请求取消”和“真实错误”
    if (axios.isCancel(error)) {
      console.log(`[请求取消] ${error.message}`)
      return Promise.reject(new Error('请求已取消'))
    }

    // 8.6 分类处理 HTTP 错误（401/404/500 等）
    let errorMsg = '网络异常，请检查网络连接'
    if (error.response) {
      const { status, data } = error.response
      switch (status) {
        case 401: // 未登录/Token 过期：跳登录页
          errorMsg = data?.message || '登录已过期，请重新登录'
          localStorage.removeItem('token')
          router.push('/login').catch(() => { }) // 跳转登录页（忽略重复警告）
          break
        case 403: // 权限不足
          errorMsg = data?.message || '没有操作权限，请联系管理员'
          break
        case 404: // 接口不存在
          errorMsg = `请求的接口不存在（${error.response.config.url}）`
          break
        case 500: // 服务器错误
          errorMsg = data?.message || '服务器内部错误，请稍后重试'
          break
        default:
          errorMsg = `请求错误（${status}）：${data?.message || '未知错误'}`
      }
    }

    if (!error.response) {
      console.error('API服务不可用，请检查后端服务是否启动')
    } else {
      ElMessage.error(errorMsg)
    }
    return Promise.reject(new Error(errorMsg))
  }
)

// 9. 封装常用请求方法（get/post/put/delete/upload）
const request = {
  // GET请求（参数拼在URL上，适合查询数据）
  get(url, params = {}, config = {}) {
    return service({
      url,          // 接口路径（如 '/quality/data'）
      method: 'get',// 请求方法
      params,       // URL参数（如 { page: 1, size: 10 }）
      ...config     // 自定义配置（如 showLoading: false，覆盖默认值）
    })
  },

  // POST请求（参数在请求体中，适合提交数据）
  post(url, data = {}, config = {}) {
    return service({
      url,
      method: 'post',
      data,         // 请求体数据（如 { name: '张三', age: 20 }）
      ...config
    })
  },

  // PUT请求（常用于全量更新数据，如修改用户信息）
  put(url, data = {}, config = {}) {
    return service({
      url,
      method: 'put',
      data,
      ...config
    })
  },

  // DELETE请求（常用于删除数据，参数可拼在URL或请求体）
  delete(url, params = {}, config = {}) {
    return service({
      url,
      method: 'delete',
      params,       // 多数场景下，DELETE参数拼在URL上
      ...config
    })
    // 若后端要求DELETE参数在请求体，可改为：
    // return service({ url, method: 'delete', data: params, ...config })
  },

  // 上传文件（FormData格式，适合图片、Excel等文件上传）
  upload(url, formData, config = {}) {
    return service({
      url,
      method: 'post',
      data: formData,  // 必须是FormData对象（如 new FormData().append('file', file)）
      headers: {
        'Content-Type': 'multipart/form-data'  // 上传文件专用Content-Type
      },
      timeout: config.timeout || 60000,        // 上传超时延长（默认60秒，避免大文件超时）
      loadingText: config.loadingText || '文件上传中...',
      ...config
    })
  },

  // 取消所有未完成的请求（如页面切换时，避免内存泄漏或无效请求）
  cancelAll(message = '所有请求已取消') {
    if (pendingRequests.size > 0) {
      pendingRequests.forEach((cancel) => {
        cancel(message)  // 触发取消请求
      })
      pendingRequests.clear()  // 清空待处理请求列表
    }
  },

  // 清除加载动画（异常场景下手动调用，如页面强制刷新前）
  clearLoading() {
    loadingCount = 0
    loadingInstance?.close()  // 关闭加载动画实例
  }
}

// 导出request对象，供组件使用
export default request